package preprocess;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import org.supercsv.io.CsvListReader;
import org.supercsv.io.CsvMapWriter;
import org.supercsv.io.ICsvMapWriter;
import org.supercsv.prefs.CsvPreference;

public class Candidates {

	/*
	 * ====================================================== 
	 * MEMBERS
	 * ======================================================
	 */
	private CsvListReader _listReader;
	private Boolean _header;

	/*
	 * ====================================================== 
	 * CONSTRUCTORS
	 * ======================================================
	 */
	public Candidates(String filename, Boolean header) {
		try {
			_listReader = new CsvListReader(new FileReader(filename),
					CsvPreference.EXCEL_PREFERENCE);
			// _listReader = new CsvListReader(new FileReader("pen-ink.csv"),
			// CsvPreference.EXCEL_PREFERENCE);

			_header = header;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	/*
	 * ====================================================== 
	 * METHODS
	 * ======================================================
	 */
	public HashMap<String, ArrayList<String> > parse() {
		try {
			
			// If the file has a header, move the cursor to the second row
			if (_header) {
				_listReader.getCSVHeader(true);
			}

			//temp store in memory: contributor -> candidate1, candidate2, etc.
			HashMap<String, ArrayList<String>> items = new HashMap<String, ArrayList<String> >();
			
			//Fields to choose
			String contributor;
			String candidate;

			// Read in the contents from the csv file
			List<String> list = _listReader.read();
			
			while (list != null) {
				//corresponds to "NAME" column in original dataset
				//contributor = list.get(15);
				//corresponds to "ZIP" column in original dataset
				contributor = list.get(23);
				
				
				//corresponds to candidate last name, first name
				candidate = list.get(4) + "_" + list.get(5);
				
				
				//contributor exists, so we add provided it is an additional (unique) candidate
				if (items.containsKey(contributor) && !items.get(contributor).contains(candidate) ) {
					items.get(contributor).add(candidate);
				}
				else {
					//case of new contributor, add new candidate list to hash
					items.put(contributor, new ArrayList<String>());
					items.get(contributor).add(candidate);
				}

				/*
				//contributor exists, so we add provided it is an additional (unique) candidate
				if (items.containsKey(candidate) && !items.get(candidate).contains(contributor) ) {
					items.get(candidate).add(contributor);
				}
				else {
					//case of new contributor, add new candidate list to hash
					items.put(candidate, new ArrayList<String>());
					items.get(candidate).add(contributor);
				}
				*/
				list = _listReader.read();
			}
			return items;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	//print method for testing verification
	public void print_any_multiples(HashMap<String, ArrayList<String>> items) {
		int line_count = 0;
		for (String contributor : items.keySet()) {
			if (items.get(contributor).size() > 1) {
				System.out.print(contributor + ": ");
				for (String candidates : items.get(contributor)) {
					System.out.print(candidates + " ");
				}
				line_count++;
				System.out.println();
			}
		}
		System.out.println("Total lines: " + line_count);
	}
	
	/*
	 * http://supercsv.sourceforge.net/codeExamples_general.html
	 *seems to run w/ support .005 - so very sparse examples, not sure if that's reasonable
	 */
	public void toCSV(HashMap<String, ArrayList<String> > items, String filename) throws Exception {
		ICsvMapWriter writer = new CsvMapWriter(new FileWriter(filename), CsvPreference.STANDARD_PREFERENCE);
		
		try {
			
			for (ArrayList<String> candidateList : items.values() ) {
				final HashMap<String, ? super Object> data1 = new HashMap<String, Object>();
				int count = 0;
				ArrayList<String> headerList = new ArrayList<String>();
				
				for(String candidate : candidateList) {
					data1.put("candidate " + count, candidate);
					
					headerList.add("candidate "+ count);
					count++;
				}		
				String [] headers = headerList.toArray(new String [headerList.size()]);
				writer.write(data1, headers);
				
			}
		}
		finally {
			writer.close();
		}
		
	
	
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Candidates Contributions = new Candidates("./data/2009_contribution.csv", true);
		HashMap<String, ArrayList<String> > items = Contributions.parse();
		
		//Contributions.print_any_multiples(items);
		try {
			Contributions.toCSV(items, "candidates.csv");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("Done");
	}

}
